/*===============================
 *Title      :  TaskController.java
 *Created  :[ 2012-3-22 上午11:03:35 ] by fanlt
 * ==============================
 * Description:   
 * Copyright  :  Copyright (c) 2012
 * Company    :  Flyfot
 * @author  <a href="fanlt@flyfot.cn">fanlt</a>
 *
 */
package org.zxstudio.encrypt.task;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import org.zxstudio.encrypt.bean.EncryptFile;
import org.zxstudio.encrypt.tree.FileTreeTraverser;
import org.zxstudio.encrypt.utils.RLog;


import android.content.Context;

/**
 * 任务调度管理
 * 
 * @author fan
 * 
 */
public class TaskController implements Runnable {

	private static final String TAG = "TaskController";
	private static final boolean DEBUG = true;

	private final Context mContext;
	private final Thread mThread;
	private final Thread mListenThread;

	private static BlockingQueue<Event> mCommands = new LinkedBlockingQueue<Event>();
	private static ArrayList<Event> mEvents = new ArrayList<Event>();
	private Event mCurrentCmds;
	private EncryptListener.CallBack mObserver;
	private EncryptListener  mEncryptListener;
	private boolean mListenerFlags = true;
	private static TaskController sInstance = null;
	private boolean mCanceled = false;
	private boolean mStartFlags = false;
	
	
	private ArrayList<String> mSucessedFiles = new ArrayList<String>();
	private ArrayList<String> mFailedFiles = new ArrayList<String>();
	private ArrayList<File> mEncryptFiles = new ArrayList<File>();
	private ArrayList<File> mEncryptFolders = new ArrayList<File>();


	public TaskController(Context _context) {
		mContext = _context;
		mThread = new Thread(this);
		mListenThread = new Thread(mListenerRunner);
		mEncryptListener = new EncryptListener();
		mThread.start();
	}

	public synchronized static TaskController getInstance(Context _context) {
		if (sInstance == null) {
			sInstance = new TaskController(_context);
		}
		return sInstance;
	}

	public void registerEncryptListener(EncryptListener.CallBack callback) {
		mObserver = callback;
	}
	

	/*
	 * @Override public void run() { // TODO: need priority //
	 * Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); while
	 * (true) { Event command; if (!mCanceled) { try { if (DEBUG) { }
	 * mCurrentCmds = mCommands.take(); } catch (InterruptedException e) {
	 * e.printStackTrace(); continue; } mCurrentCmds.runnable.run(); } } }
	 */

	@Override
	public void run() {
		RLog.v(TAG,"main thread start run..........");
		while (true) {
			Event command;
			if (!mCanceled) {
				RLog.v(TAG,"main run .canceld:"+!mCanceled);
				try {
					if (DEBUG) {
						RLog.v(TAG, "start run:");
					}
					
					if (mCommands.size() == 0 && mStartFlags) {
						if (mObserver != null) {
							mObserver.notifyResult(mEncryptListener.getSucess(), mEncryptListener.getFailed());
							mStartFlags = false;
						}
					
					}
					
					mCurrentCmds = mCommands.take();
				} catch (InterruptedException e) {
					e.printStackTrace();
					continue;
				}
				mCurrentCmds.runnable.run();
			} 
		}
		
	}
      /**
       * 对外提供的加密接口
       * @param bean  file的集合
       */
	public void encrypt(List<File> bean) {
		final EncryptMachine machine = FileEncryptMachine.getInstance(mContext);
		machine.registerEncryptListener(mEncryptListener);
		// 在中断的情况下，不允许重新加载任务
		if (!mCanceled) {
			for (final File file : bean) {
				Runnable runnable = new Runnable() {

					@Override
					public void run() {
						if (machine != null) {
							boolean result = machine.ecrypt(file);

							if (DEBUG) {
								RLog.v(TAG, file.getAbsolutePath() + " 加密结果是" + result);
							}
						}
				
					}

				};
				Event cmd = new Event();
				cmd.uri = file.getAbsolutePath();
				cmd.runnable = runnable;
				put(cmd);
			}
		}
	}
	/**
	 * 对外提供解密接口
	 * @param Ids id的集合
	 */
	public void decrypt(List<Long> Ids) {
		final EncryptMachine machine = FileEncryptMachine.getInstance(mContext);
		machine.registerEncryptListener(mEncryptListener);
		// 在中断的情况下，不允许重新加载任务
		if (!mCanceled) {
			for (final long id : Ids) {
				Runnable runnable = new Runnable() {

					@Override
					public void run() {
						if (machine != null) {
							boolean result = machine.decrypt(id);
						}
				
					}

				};
				Event cmd = new Event();
				cmd.runnable = runnable;
				put(cmd);
			}
		}
	}
	private Runnable mListenerRunner = new Runnable() {

		@Override
		public void run() {
			while (mListenerFlags) {
				if (mCurrentCmds != null) {
				} else {
					continue;
				}
			}
		}

	};

	private void put(Event event) {
		try {
			mStartFlags = true;
			mCommands.add(event);
			//mEvents.add(event);
		} catch (Exception e) {

		}
	}
	/**
	 * 暂停任务
	 */
	public void pauseTask() {
		RLog.v(TAG, "pauseTask");
		mCanceled = true;
	}

	public void pause() {
		pauseTask();
	}

	/**
	 * 重新开始任务
	 */
	public void restartTask() {
		mCanceled = false;
	}

	/**
	 * 在任务结束的情况下，任务列表里必须清空。
	 */
	public void stopTask() {
		mCanceled = false;
		// mCommands.clear();
		mEvents.clear();
	}

	private class Event {
		String uri;
		Runnable runnable;
	}

}
